#ifndef __EB_GPIO_H__
#define __EB_GPIO_H__

#include <types.h>
#include <drivers/gpio_pin.h>


struct gpio_conf {
    uint16_t  pin;
    uint16_t  mux;
    uint8_t   drv;
    uint8_t   dir: 4;
    uint8_t   val: 4;
};


struct gpio_desc;


struct gpio_ops {
    int  (*request_pin)(struct gpio_desc *desc, uint16_t pin);
    void (*free_pin)(struct gpio_desc *desc, uint16_t pin);
    void (*set_mux)(uint16_t pin, uint8_t mux);
    void (*set_dir)(uint16_t pin, uint8_t flag);
    void (*set_drv)(uint16_t pin, uint8_t drv);
    void (*set_value)(uint16_t pin, uint8_t value);
    int  (*get_value)(uint16_t pin);
    int  (*set_exti)(uint16_t pin, int flag);
};


struct gpio_desc {
    /* gpio_desc name */
    const char *name;
    /* pin count */
    const uint32_t npins;
    /* gpio_desc operation */
    struct gpio_ops *ops;
    /* all pin bit map, for busy status */
    uint8_t *map;
};


int gpio_desc_register(struct gpio_desc *desc);
int gpio_request(uint16_t pin);
int gpio_request_conf(const struct gpio_conf *conf, uint32_t npins);
void gpio_set_value(uint16_t pin, uint8_t value);
void gpio_toggle_value(uint16_t pin);
int gpio_get_value(uint16_t pin);
int gpio_direction_intput(uint16_t pin);
int gpio_direction_output(uint16_t pin, uint8_t value);
void gpio_free(uint16_t pin);
int gpio_to_irq(uint16_t pin, int flag);
int gpio_mux_func(const struct gpio_conf *func, uint16_t npins);
void gpio_mux_free(const struct gpio_conf *func, uint16_t npins);


#endif // !__EB_GPIO_H__
